import Vue, {
  computed,
  defineComponent,
  getCurrentInstance,
  provide,
  Ref,
  watch,
} from 'vue'
import {
  createSchemaField,
  RecursionField,
  useField,
  useFieldSchema,
  useForm,
  Field,
  ArrayField,
  ObjectField,
} from '@formily/vue'
import {
  createForm,
  Form,
  FormPath,
  onFieldMount,
  onFieldReact,
  onFormInit,
  onFormMount,
  ObjectField as IObjectField
} from '@formily/core'
import { inject, ref, shallowRef } from 'vue'
import { RouteParams, useRoute, useRouter } from 'vue-router'
import { composeExport } from '@formily/vxe-table/src/__builtins__'
import {
  useTableInstance,
  VXETablePropsSymbol,
  ArrayTable,
} from '@formily/vxe-table/src/array-table'
import {
  Table,
  Column,
  Colgroup,
  Pager,
  Select,
  Option,
  Optgroup,
  Grid,
  Button,
  VxeTableProps,
  VxeGridEventProps,
} from 'vxe-table'
import { useBFGridDomain, useBFGridServices } from './domain-base'
import { Toolbar } from './toolbar'

const Pagination = defineComponent({
  props: { value: { type: Object, default: () => ({}) } },
  emits: ['change'],
  setup(props, { attrs, slots, emit }) {
    // const prefixCls = `${stylePrefix}-array-table`
    const formRef = useForm()
    return () => {
      const pagerField = usePagerField(formRef.value)
      return (
        <div>
          <Pager
            {...attrs}
            currentPage={pagerField?.value?.currentPage}
            pageSize={pagerField?.value?.pageSize}
            total={pagerField?.value?.total}
            pageSizes={[20, 50, 100, 200, 300, 500, 1000, 2000, 5000]}
            onPageChange={(arg) => {
              const { currentPage, pageSize, $pager } = arg
              emit('change', {
                ...pagerField.value,
                currentPage,
                pageSize,
              })
            }}
          />
        </div>
      )
    }
  },
})

export const GridSortPath = new FormPath('gridapp.sorts')
export const GridSelectionPath = new FormPath('gridapp.selections')
export const GridPagerPath = new FormPath('gridapp.pager')
export const GridTablePath = new FormPath('gridapp.table')
export const GridFormPath = new FormPath('gridapp.form')

export function useSortField(form: Form) {
  return form.query(GridSortPath).take() as IObjectField
}
export function useSelectionField(form: Form) {
  return form.query(GridSelectionPath).take() as IObjectField
}
export function usePagerField(form: Form) {
  return form.query(GridPagerPath).take() as IObjectField
}
export function useTableField(form: Form) {
  return form.query(GridTablePath).take() as IObjectField
}
export function useFormField(form: Form) {
  return form.query(GridFormPath).take() as IObjectField
}
// actions: {}, // 按钮
// links: { type: Array }, // 链接
const GridInner = defineComponent({
  props: ['value', 'onChange'],
  setup(props, { slots, attrs }) {
    const modelRef = inject('model', ref())
    const prefixRef = inject('prefix', ref('bf-'))
    const $router = useRouter()
    const $route = useRoute()
    const domainModelRef = useBFGridDomain()
    const schemaRef = useFieldSchema()
    const formRef = useForm()
    formRef.value.addEffects('pager|selections', (form) => {
      onFieldMount('gridapp.table', (field, form) => {
        const sortField = useSortField(form)
        const selectionsField = useSelectionField(form)
        const originalProps = field.componentProps

        const hookMethods: Partial<VxeGridEventProps> = [
          'onSortChange',
          'onClearSort',
          'onCheckboxChange',
          'onRadioChange',
          'onCurrentChange',
          'onCheckboxAll',
        ].reduce((buffer, name) => {
          buffer[name] = originalProps[name]
          return buffer
        }, {})
        // 代理sort时间
        field.setComponentProps({
          ...originalProps,
          onSortChange: (args) => {
            const sortList = args.sortList.map((list) => {
              const { column, ...rest } = list
              return rest
            })
            sortField.setValue(sortList)
            hookMethods?.onSortChange?.(args)
          },
          onCheckboxAll: (args) => {
            const { $table } = args
            const rows = $table.getCheckboxRecords()
            $table.clearRadioRow()
            selectionsField.setValue({
              ...selectionsField.value,
              ids: rows.map((row) => row[selectionsField.value.key]),
              record: rows,
            })
            hookMethods?.onCheckboxAll?.(args)
          },
          onCheckboxChange: (args) => {
            const { $table } = args
            const rows = $table.getCheckboxRecords()
            $table.clearRadioRow()
            selectionsField.setValue({
              ...selectionsField.value,
              ids: rows.map((row) => row[selectionsField.value.key]),
              record: rows,
            })
            hookMethods?.onCheckboxChange?.(args)
          },
          onRadioChange: (args) => {
            const { row, $table } = args
            $table.clearCheckboxRow()
            selectionsField.setValue({
              ...selectionsField.value,
              ids: [row[selectionsField.value.key]],
              record: [row],
            })
            hookMethods?.onRadioChange?.(args)
          },
        })
      })
    })

    // TODO::提供出services和model供links和actions调用
    return () => {
      const pagerField = usePagerField(formRef.value)
      const className = prefixRef.value + 'schema-app'
      const model = modelRef.value
      const schema = schemaRef.value
      // 根据当前路由的变化（query,params)进行links的修改
      const properties = schema.reduceProperties(
        (buffer, schema, key, index) => {
          const componentName = schema['x-component'] as string
          if (componentName.startsWith('BFGridApp.')) {
            buffer[
              componentName.substring(10, componentName.length).toLowerCase()
            ] = schema
          }
          return buffer
        },
        {}
      )

      // 根据不同的方式render views 比如edit,detail,info
      function renderDialog() { }
      function renderDrawer() { }
      function renderCards() {
        if (!properties['cards']) return null
        return (
          <RecursionField
            name="cards"
            schema={properties['cards']}
          ></RecursionField>
        )
      }
      function renderTable() {
        if (!properties['table']) return null
        return (
          <RecursionField
            name="table"
            schema={properties['table']}
          ></RecursionField>
        )
      }
      function renderForm() {
        if (!properties['form']) return null
        return (
          <RecursionField
            name="form"
            schema={properties['form']}
          ></RecursionField>
        )
      }
      function renderToolbar() {
        if (!properties['toolbar']) return null
        return (
          <RecursionField
            name="toolbar"
            schema={properties['toolbar']}
          ></RecursionField>
        )
      }
      function renderTop() {
        if (!properties['top']) return null
        return (
          <RecursionField
            name="top"
            schema={properties['top']}
          ></RecursionField>
        )
      }
      function renderLeft() {
        if (!properties['left']) return null
        return (
          <RecursionField
            name="left"
            schema={properties['left']}
          ></RecursionField>
        )
      }
      function renderRight() {
        if (!properties['right']) return null
        return (
          <RecursionField
            name="right"
            schema={properties['right']}
          ></RecursionField>
        )
      }
      function renderBottom() {
        if (!properties['bottom']) return null
        return (
          <RecursionField
            name="bottom"
            schema={properties['bottom']}
          ></RecursionField>
        )
      }
      function renderUtils() {
        return (
          <>
            <ObjectField name="pager" component={[Pagination, {}]} />
            <ObjectField name="selections" />
            <ObjectField name="sorts" />
          </>
        )
      }
      return (
        <div class={className}>
          <div class={`${className}__body`}>
            <div class={`${className}__left`}>{renderLeft()}</div>
            <div class={`${className}__main`}>
              <div class={`${className}__form`}>{renderForm()}</div>
              <div class={`${className}__toolbar`}>{renderToolbar()}</div>
              <div class={`${className}__top`}>{renderTop()}</div>
              {renderCards()}
              {renderTable()}
              {renderUtils()}
              <div class={`${className}__bottom`}>{renderBottom()}</div>
            </div>
            <div class={`${className}__right`}>{renderRight()}</div>
          </div>
        </div>
      )
    }
  },
})

export const BFGridApp = composeExport(GridInner, {
  Table: ArrayTable,
  Form: (props, context) => context.slots?.default?.(),
  Toolbar: Toolbar,
  Top: (props, context) => context.slots?.default?.(),
  Left: (props, context) => context.slots?.default?.(),
  Right: (props, context) => context.slots?.default?.(),
  Bottom: (props, context) => context.slots?.default?.(),
})
